home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / doom / suckmods.zip / SUCKMODS.ZIP / suck05 / src / oldcombat.qc < prev    next >
Text File  |  1997-05-09  |  14KB  |  616 lines

  1.  
  2. void() T_MissileTouch;
  3. void() info_player_start;
  4. void(entity targ, entity attacker) ClientObituary;
  5.  
  6.  
  7. //============================================================================
  8.  
  9. /*
  10. ============
  11. CanDamage
  12.  
  13. Returns true if the inflictor can directly damage the target.  Used for
  14. explosions and melee attacks.
  15. ============
  16. */
  17. float(entity targ, entity inflictor) CanDamage =
  18. {
  19. // bmodels need special checking because their origin is 0,0,0
  20.     if (targ.movetype == MOVETYPE_PUSH)
  21.     {
  22.         traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
  23.         if (trace_fraction == 1)
  24.             return TRUE;
  25.         if (trace_ent == targ)
  26.             return TRUE;
  27.         return FALSE;
  28.     }
  29.     
  30.     traceline(inflictor.origin, targ.origin, TRUE, self);
  31.     if (trace_fraction == 1)
  32.         return TRUE;
  33.     traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
  34.     if (trace_fraction == 1)
  35.         return TRUE;
  36.     traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
  37.     if (trace_fraction == 1)
  38.         return TRUE;
  39.     traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
  40.     if (trace_fraction == 1)
  41.         return TRUE;
  42.     traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
  43.     if (trace_fraction == 1)
  44.         return TRUE;
  45.  
  46.     return FALSE;
  47. };
  48.  
  49.  
  50. /*
  51. ============
  52. Killed
  53. ============
  54. */
  55. void(entity targ, entity attacker) Killed =
  56. {
  57.     local entity oself, tempe, onew, oother;
  58.  
  59.     oself = self;
  60.     self = targ;
  61.     
  62.     if (self.health < -99)
  63.         self.health = -99;        // don't let sbar look bad if a player
  64.  
  65.     if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
  66.     {    // doors, triggers, etc
  67.  
  68.         self.th_die ();
  69.         self = oself;
  70.         return;
  71.     }
  72.  
  73.     if (attacker.rune_num == ITEM_RUNE_SARGON)
  74.     {
  75.         tempe=spawn();
  76.         tempe.ammo_rockets=self.ammo_rockets;
  77.         tempe.ammo_shells=self.ammo_shells;
  78.         tempe.ammo_nails=self.ammo_nails;
  79.         tempe.ammo_cells=self.ammo_cells;
  80.         tempe.items=self.items;
  81.         tempe.owner = targ;
  82.         tempe.items = 0;
  83.         onew=self;
  84.         oother = other;
  85.         self=tempe;
  86.         other=attacker;
  87.         BackpackTouch();
  88.         other=oother;
  89.         self=onew;
  90.         self.ammo_rockets=0;
  91.         self.ammo_shells=0;
  92.         self.ammo_nails=0;
  93.         self.ammo_cells=0;
  94.         self.items=0;    
  95.     }
  96.  
  97.     self.enemy = attacker;
  98.  
  99.     ClientObituary(self, attacker);
  100.     
  101.     self.takedamage = DAMAGE_NO;
  102.     self.touch = SUB_Null;
  103.  
  104.     self.th_die ();
  105.     
  106.     self = oself;
  107. };
  108.  
  109.  
  110. // *TEAMPLAY*
  111. // Prototypes
  112.  
  113. float(entity targ, entity inflictor, entity attacker, float damage) TeamArmorDam;
  114. float(entity targ, entity inflictor, entity attacker, float damage) TeamHealthDam;
  115.  
  116. /*
  117. ============
  118. T_Damage
  119.  
  120. The damage is coming from inflictor, but get mad at attacker
  121. This should be the only function that ever reduces health.
  122. ============
  123. */
  124. void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
  125. {
  126.     local    vector    dir;
  127.     local    entity    oldself;
  128.     local    float    save;
  129.     local    float    take;
  130.     local     string    tmp_string;
  131.     local     float    tmp_float, tmp2;
  132.     local     entity    e;
  133.     local   float  attacker_tmts, targ_tmts;
  134.         
  135.  
  136.     if (!targ.takedamage)
  137.         return;
  138.  
  139.     if ((targ.rune_num == ITEM_RUNE_LOKI) && (targ.loki_possessed) &&
  140.         (!(targ.player_flag&ITEM_ENEMY_FLAG)))
  141.         return;
  142.  
  143.     //SUCK: Figure the momentum change first
  144.     if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
  145.     {
  146.         dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
  147.         dir = normalize(dir);
  148.         targ.velocity = targ.velocity + dir*damage*8;
  149.  
  150.     }
  151.  
  152.     if ((attacker == targ) && (attacker.rune_num == ITEM_RUNE_IFRITE))
  153.         return;
  154.  
  155.     if ((targ == attacker) && (attacker.rune_num == ITEM_RUNE_MARS))
  156.         damage = damage / 1.5;
  157.  
  158.     if (attacker.rune_num == ITEM_RUNE_MARS)
  159.         damage=damage*2.5;
  160.     if (targ.rune_num == ITEM_RUNE_GOLOM)
  161.         damage = damage / 4;
  162.  
  163.  
  164.     if (attacker.rune_num == ITEM_RUNE_KIZI)
  165.     {
  166.         if (attacker.health <= 25)
  167.             damage = damage * 3;
  168.         else if (attacker.health < 50)
  169.             damage = damage * 2;
  170.         else if (attacker.health < 65)
  171.             damage = damage * 1.5;
  172.     }
  173.  
  174.     // Sargon does double damage to the judaic set
  175.     if ((attacker.rune_num == ITEM_RUNE_SARGON) &&
  176.         ((targ.rune_num == ITEM_RUNE_GOLOM) ||
  177.         (targ.rune_num == ITEM_RUNE_SHYLOCK) ||
  178.         (targ.rune_num == ITEM_RUNE_SAMPSON) ||
  179.         (targ.rune_num == ITEM_RUNE_DAVID)))
  180.         damage = damage * 2;
  181.     else if ((attacker.rune_num == ITEM_RUNE_SARGON) &&
  182.         (targ.player_flag&ITEM_ENEMY_FLAG))
  183.         damage = damage * 2;
  184.  
  185.     if (targ.rune_num == ITEM_RUNE_MARS)
  186.         damage=damage*1.8;
  187.  
  188.     if ((attacker.rune_num == ITEM_RUNE_VAMPIRE) &&
  189.         (attacker.team != targ.team) &&
  190.         (targ.classname == "player"))
  191.     {
  192.         if (attacker.health<170)
  193.         {
  194.             tmp_float = damage/3;
  195.             attacker.health=attacker.health + tmp_float;
  196.             if (attacker.health>200)
  197.                 attacker.health = 200;
  198.         }
  199.     }
  200.  
  201.     if ((attacker.rune_num == ITEM_RUNE_WENDIGO) && (targ!=attacker))
  202.     {
  203.         targ.lock_velocity=targ.velocity;
  204.         targ.lock_time=time+1.5;
  205.     }
  206.  
  207. // used by buttons and triggers to set activator for target firing
  208.     damage_attacker = attacker;
  209.  
  210.     //SUCK: Increase damage of attacker by 10% for every teammate close to him
  211.     //  and increase resistance of target by 10% for every teammate close to him.
  212.     if (teamplay&TEAM_GROUP_POWER)
  213.     {
  214.         attacker_tmts=0;
  215.         e=findradius(attacker.origin, 300);
  216.         while (e)
  217.         {
  218.             if (e.classname == "player")
  219.             {
  220.                 if (e.team == attacker.team)
  221.                     attacker_tmts=attacker_tmts + 1;
  222.             }
  223.             e=e.chain;
  224.         }
  225.         tmp_string=ftos(attacker_tmts);
  226.         targ_tmts=0;
  227.         e=findradius(targ.origin, 300);
  228.         while (e)
  229.         {
  230.             if (e.classname == "player")
  231.             {
  232.                 if (e.team == targ.team)
  233.                     targ_tmts=targ_tmts + 1;
  234.             }
  235.             e=e.chain;
  236.         }
  237.         tmp_string=ftos(targ_tmts);
  238.         while(attacker_tmts>0)
  239.         {
  240.             damage=damage*1.1;
  241.             attacker_tmts=attacker_tmts - 1;
  242.         }
  243.         while (targ_tmts>0)
  244.         {
  245.             damage=damage*0.9;
  246.             targ_tmts=targ_tmts - 1;
  247.         }
  248.     }
  249.  
  250.     // SUCK: If the player has the rune of castle, then his resistance and damage
  251.     // increase when he is near his flag
  252.     if (attacker.rune_num == ITEM_RUNE_CASTLE)
  253.     {
  254.         attacker_tmts=0;
  255.         e=findradius(attacker.origin, 800);
  256.         while (e)
  257.         {
  258.             if (((e.classname == "item_flag_team1") && (attacker.team == (TEAM_COLOR1 + 1))) ||
  259.                 ((e.classname == "item_flag_team2") && (attacker.team == (TEAM_COLOR2 + 1))))
  260.                 attacker_tmts=1;
  261.             e=e.chain;
  262.         }
  263.         if (attacker_tmts == 1)
  264.             damage = damage * 4;
  265.         else
  266.             damage = damage    * 0.9;
  267.     }
  268.  
  269.     if (targ.rune_num == ITEM_RUNE_CASTLE)
  270.     {
  271.         attacker_tmts=0;
  272.         e=findradius(targ.origin, 800);
  273.         while (e)
  274.         {
  275.             if (((e.classname == "item_flag_team1") && (targ.team == (TEAM_COLOR1 + 1))) ||
  276.                 ((e.classname == "item_flag_team2") && (targ.team == (TEAM_COLOR2 + 1))))
  277.                 targ_tmts=1;
  278.             e=e.chain;
  279.         }
  280.         if (targ_tmts == 1)
  281.             damage = damage / 3;
  282.         else
  283.             damage = damage * 1.3;
  284.     }
  285.  
  286.     // SUCK: If he has the rune of siege, then he becomes more powerful
  287.     // near the ENEMY flag or if he has it.
  288.     if ((attacker.rune_num == ITEM_RUNE_SIEGE) &&
  289.         (attacker.player_flag&ITEM_ENEMY_FLAG))
  290.     {
  291.         damage = damage * 2;
  292.         if (attacker.super_sound< time)
  293.         {
  294.             sound (attacker, CHAN_ITEM, "items/damage3.wav", 1, ATTN_NORM);
  295.             attacker.super_sound = time + 1;
  296.         }
  297.     }
  298.     else if (attacker.rune_num == ITEM_RUNE_SIEGE)
  299.     {
  300.         attacker_tmts=0;
  301.         e=findradius(attacker.origin, 800);
  302.         while (e)
  303.         {
  304.             if (((e.classname == "item_flag_team1") && (attacker.team == (TEAM_COLOR2 + 1))) ||
  305.                 ((e.classname == "item_flag_team2") && (attacker.team == (TEAM_COLOR1 + 1))))
  306.                 attacker_tmts=1;
  307.             e=e.chain;
  308.         }
  309.         if (attacker_tmts == 1)
  310.         {
  311.             damage = damage * 2;
  312.  
  313.             if (attacker.super_sound< time)
  314.             {
  315.                 sound (attacker, CHAN_ITEM, "items/damage3.wav", 1, ATTN_NORM);
  316.                 attacker.super_sound = time + 1;
  317.             }
  318.         }
  319.     }
  320.     if ((targ.rune_num == ITEM_RUNE_SIEGE) &&
  321.         (targ.player_flag & ITEM_ENEMY_FLAG))
  322.     {
  323.         damage = damage / 2;
  324.         if (targ.invincible_sound < time) 
  325.         {
  326.         sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  327.         targ.invincible_sound = time + 2;
  328.         }
  329.     }
  330.     else if (targ.rune_num == ITEM_RUNE_SIEGE)
  331.     {
  332.         attacker_tmts=0;
  333.         e=findradius(targ.origin, 800);
  334.         while (e)
  335.         {
  336.             if (((e.classname == "item_flag_team1") && (targ.team == (TEAM_COLOR2 + 1))) ||
  337.                 ((e.classname == "item_flag_team2") && (targ.team == (TEAM_COLOR1 + 1))))
  338.                 targ_tmts=1;
  339.             e=e.chain;
  340.         }
  341.         if (targ_tmts == 1)
  342.         {
  343.             damage = damage / 2;
  344.             if (targ.invincible_sound < time) {
  345.                 sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  346.                 targ.invincible_sound = time + 2;
  347.             }
  348.         }
  349.         else
  350.             damage = damage;
  351.     }
  352.  
  353. // check for quad damage powerup on the attacker
  354.     if (attacker.super_damage_finished > time)
  355.         damage = damage * 4;
  356.  
  357. // RUNE: check for double damage for rune of Black Magic powerup
  358.     if (attacker.rune_num == ITEM_RUNE_DBLDMG)
  359.         damage = damage * 2;
  360.     if ((attacker.rune_num == ITEM_RUNE_VAMPIRE) ||
  361.         (attacker.rune_num == ITEM_RUNE_VIKING))
  362.         damage = damage * 1.3;
  363.  
  364.     if ((targ.rune_num == ITEM_RUNE_ARTHUR) &&
  365.         (attacker.classname == "player"))
  366.         damage = damage / 2;
  367.  
  368.     if ((targ.rune_num == ITEM_RUNE_VIKING) &&
  369.         (attacker.rune_num == ITEM_RUNE_ARTHUR))
  370.         damage = damage * 3;
  371.  
  372.     if ((attacker.rune_num == ITEM_RUNE_WITCH) &&
  373.         (targ.classname == "player") &&
  374.         (targ.curse_time == 0) && (random() < 0.8) &&
  375.         (targ.team != attacker.team))
  376.     {
  377.         targ.msg_center = 1;
  378.         clientmsg(targ, "You have been cursed!\n");
  379.         targ.curse_time = time + 7;
  380.     }
  381.     if ((attacker.rune_num == ITEM_RUNE_BALDER) &&
  382.         (targ.team != attacker.team) && (random() < 0.9))
  383.     {
  384.         targ.balder_slowdown = targ.balder_slowdown + 1;
  385.         targ.balder_time = time + 1;
  386.     }
  387.  
  388.     // The viking fucks up the priest
  389.     if ((attacker.rune_num == ITEM_RUNE_VIKING) &&
  390.         (targ.rune_num == ITEM_RUNE_PRIEST))
  391.         damage = damage * 3;
  392.  
  393. // save damage based on the target's armor level
  394.  
  395. // *TEAMPLAY*
  396. // TeamArmorDam returns true iff the attacker can damage the target's armor
  397.  
  398.     if (TeamArmorDam(targ, inflictor, attacker, damage))
  399.         save = ceil(targ.armortype*damage);
  400.     else
  401.         save = 0;
  402.  
  403.     // SUCK: The werewolf doesn't lose armor
  404.     if (targ.rune_num == ITEM_RUNE_WEREWOLF)
  405.         save=0;
  406.  
  407.     if (save >= targ.armorvalue)
  408.     {
  409.         save = targ.armorvalue;
  410.         targ.armortype = 0;    // lost all armor
  411.         targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
  412.     }
  413.     
  414.     take = ceil(damage-save);
  415.  
  416.     if (targ.rune_num == ITEM_RUNE_VULCAN)
  417.         take = take / 2;
  418.  
  419. //RUNE check if target has rune of Earth Magic (half damage)
  420.     if (targ.rune_num == ITEM_RUNE_RESIST) {
  421.         take = take / 2;
  422.         save = save / 2;
  423.         if (targ.invincible_sound < time) {
  424.             sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  425.             targ.invincible_sound = time + 2;
  426.         }
  427.     }
  428.  
  429.  
  430.     targ.armorvalue = targ.armorvalue - save;
  431.  
  432.     if ((targ.rune_num == ITEM_RUNE_SHYLOCK) &&
  433.         (targ != attacker) && (attacker.classname == "player"))
  434.     {
  435.         attacker.deathweapon="shylock";
  436.         T_Damage(attacker, targ, targ, damage);
  437.         attacker.deathweapon="";
  438.  
  439.     }
  440.  
  441.  
  442.     //SUCK: Vampires take 0.8x damage.
  443.     if (targ.rune_num == ITEM_RUNE_VAMPIRE) 
  444.     {
  445.         take = take * 0.8;
  446.         if (targ.rune_sound_start < time) 
  447.         {
  448.             sound(targ, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_NORM);
  449.             targ.rune_sound_start = time + 2.5;
  450.         }
  451.     }
  452.  
  453. // add to the damage total for clients, which will be sent as a single
  454. // message at the end of the frame
  455. // FIXME: remove after combining shotgun blasts?
  456.     if (targ.flags & FL_CLIENT)
  457.     {
  458.         targ.dmg_take = targ.dmg_take + take;
  459.         targ.dmg_save = targ.dmg_save + save;
  460.         targ.dmg_inflictor = inflictor;
  461.     }
  462.  
  463. // check for godmode or invincibility
  464.     if (targ.flags & FL_GODMODE)
  465.         return;
  466.     if (targ.invincible_finished >= time)
  467.     {
  468.         if (self.invincible_sound < time)
  469.         {
  470.             sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  471.             self.invincible_sound = time + 2;
  472.         }
  473.         return;
  474.     }
  475.  
  476.     
  477. // team play damage avoidance
  478.     if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
  479.         return;
  480.  
  481. // *TEAMPLAY*
  482. // TeamHealthDam will return true if the attacker can damage the target's
  483. // health
  484.  
  485.             
  486. // do the damage
  487.     targ.health = targ.health - take;
  488.         if (!TeamHealthDam(targ, inflictor, attacker, damage))
  489.         targ.health = targ.health + take;
  490.         
  491.         if (!TeamHealthDam(targ, inflictor, attacker, damage))
  492.         return;
  493.  
  494.     if (targ.health <= 0)
  495.     {
  496.         Killed (targ, attacker);
  497.         return;
  498.     }
  499.  
  500.  
  501. // react to the damage
  502.     oldself = self;
  503.     self = targ;
  504.  
  505.     if (self.th_pain)
  506.     {
  507.         self.th_pain (attacker, take);
  508.     }
  509.  
  510.     self = oldself;
  511. };
  512.  
  513. /*
  514. ============
  515. T_RadiusDamage
  516. ============
  517. */
  518. void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
  519. {
  520.     local    float     points;
  521.     local    entity    head;
  522.     local    vector    org;
  523.  
  524.     if (attacker.rune_num == ITEM_RUNE_IFRITE)
  525.         head = findradius(inflictor.origin, (damage+40)*1.4);
  526.     else
  527.         head = findradius(inflictor.origin, damage+40);
  528.     
  529.     while (head)
  530.     {
  531.         if (head != ignore)
  532.         {
  533.             if (head.takedamage)
  534.             {
  535.                 org = head.origin + (head.mins + head.maxs)*0.5;
  536.                 points = 0.5*vlen (inflictor.origin - org);
  537.                 if (points < 0)
  538.                     points = 0;
  539.                 points = damage - points;
  540.                 if (head == attacker)
  541.                     points = points * 0.5;
  542.                 if ((points > 0) && CanDamage(head, inflictor))
  543.                     T_Damage (head, inflictor, attacker, points);
  544.             }
  545.         }
  546.         head = head.chain;
  547.     }
  548. };
  549. /*
  550. ============
  551. T_DischargeDamage
  552. ============
  553. */
  554. void(entity inflictor, entity attacker, float damage, entity ignore) T_DischargeDamage =
  555. {
  556.     local    float     points;
  557.     local    entity    head;
  558.     local    vector    org;
  559.  
  560.     head = findradius(inflictor.origin, damage+40);
  561.     
  562.     while (head)
  563.     {
  564.         if (head != ignore)
  565.         {
  566.             if (head.takedamage)
  567.             {
  568.                 org = head.origin + (head.mins + head.maxs)*0.5;
  569.                 points = 0.5*vlen (inflictor.origin - org);
  570.                 if (points < 0)
  571.                     points = 0;
  572.                 points = damage - points;
  573.                 if (head == attacker)
  574.                     points = points * 0.5;
  575.                 if (points > 0)
  576.                 {
  577.                     if (CanDamage (head, inflictor))
  578.                         if (head.waterlevel > 1)
  579.                             T_Damage (head, inflictor, attacker, points);
  580.                 }
  581.             }
  582.         }
  583.         head = head.chain;
  584.     }
  585. };
  586.  
  587. /*
  588. ============
  589. T_BeamDamage
  590. ============
  591. */
  592. void(entity attacker, float damage) T_BeamDamage =
  593. {
  594.     local    float     points;
  595.     local    entity    head;
  596.     
  597.     head = findradius(attacker.origin, damage+40);
  598.     
  599.     while (head)
  600.     {
  601.         if (head.takedamage)
  602.         {
  603.             points = 0.5*vlen (attacker.origin - head.origin);
  604.             if (points < 0)
  605.                 points = 0;
  606.             points = damage - points;
  607.             if (head == attacker)
  608.                 points = points * 0.5;
  609.             if ((points > 0) && CanDamage(head, attacker))
  610.                 T_Damage (head, attacker, attacker, points);
  611.         }
  612.         head = head.chain;
  613.     }
  614. };
  615.  
  616.